/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package facades.persistence;

import facades.persistence.exceptions.NonexistentEntityException;
import facades.persistence.exceptions.RollbackFailureException;
import java.io.Serializable;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;
import javax.transaction.UserTransaction;

/**
 *
 * @author Alvaro
 */
public class UserJpaController implements Serializable {

    public UserJpaController(UserTransaction utx, EntityManagerFactory emf) {
        this.utx = utx;
        this.emf = emf;
    }
    private UserTransaction utx = null;
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(User user) throws RollbackFailureException, Exception {
        if (user.getMovementWisaFastercardList() == null) {
            user.setMovementWisaFastercardList(new ArrayList<MovementWisaFastercard>());
        }
        if (user.getMovementFailpalList() == null) {
            user.setMovementFailpalList(new ArrayList<MovementFailpal>());
        }
        if (user.getMovementList() == null) {
            user.setMovementList(new ArrayList<Movement>());
        }
        if (user.getMovementTransferList() == null) {
            user.setMovementTransferList(new ArrayList<MovementTransfer>());
        }
        EntityManager em = null;
        try {
            utx.begin();
            em = getEntityManager();
            List<MovementWisaFastercard> attachedMovementWisaFastercardList = new ArrayList<MovementWisaFastercard>();
            for (MovementWisaFastercard movementWisaFastercardListMovementWisaFastercardToAttach : user.getMovementWisaFastercardList()) {
                movementWisaFastercardListMovementWisaFastercardToAttach = em.getReference(movementWisaFastercardListMovementWisaFastercardToAttach.getClass(), movementWisaFastercardListMovementWisaFastercardToAttach.getIdmovementWisaFastercard());
                attachedMovementWisaFastercardList.add(movementWisaFastercardListMovementWisaFastercardToAttach);
            }
            user.setMovementWisaFastercardList(attachedMovementWisaFastercardList);
            List<MovementFailpal> attachedMovementFailpalList = new ArrayList<MovementFailpal>();
            for (MovementFailpal movementFailpalListMovementFailpalToAttach : user.getMovementFailpalList()) {
                movementFailpalListMovementFailpalToAttach = em.getReference(movementFailpalListMovementFailpalToAttach.getClass(), movementFailpalListMovementFailpalToAttach.getIdmovementPaypal());
                attachedMovementFailpalList.add(movementFailpalListMovementFailpalToAttach);
            }
            user.setMovementFailpalList(attachedMovementFailpalList);
            List<Movement> attachedMovementList = new ArrayList<Movement>();
            for (Movement movementListMovementToAttach : user.getMovementList()) {
                movementListMovementToAttach = em.getReference(movementListMovementToAttach.getClass(), movementListMovementToAttach.getIdmovement());
                attachedMovementList.add(movementListMovementToAttach);
            }
            user.setMovementList(attachedMovementList);
            List<MovementTransfer> attachedMovementTransferList = new ArrayList<MovementTransfer>();
            for (MovementTransfer movementTransferListMovementTransferToAttach : user.getMovementTransferList()) {
                movementTransferListMovementTransferToAttach = em.getReference(movementTransferListMovementTransferToAttach.getClass(), movementTransferListMovementTransferToAttach.getIdmovementTransfer());
                attachedMovementTransferList.add(movementTransferListMovementTransferToAttach);
            }
            user.setMovementTransferList(attachedMovementTransferList);
            em.persist(user);
            for (MovementWisaFastercard movementWisaFastercardListMovementWisaFastercard : user.getMovementWisaFastercardList()) {
                User oldUserIduserOfMovementWisaFastercardListMovementWisaFastercard = movementWisaFastercardListMovementWisaFastercard.getUserIduser();
                movementWisaFastercardListMovementWisaFastercard.setUserIduser(user);
                movementWisaFastercardListMovementWisaFastercard = em.merge(movementWisaFastercardListMovementWisaFastercard);
                if (oldUserIduserOfMovementWisaFastercardListMovementWisaFastercard != null) {
                    oldUserIduserOfMovementWisaFastercardListMovementWisaFastercard.getMovementWisaFastercardList().remove(movementWisaFastercardListMovementWisaFastercard);
                    oldUserIduserOfMovementWisaFastercardListMovementWisaFastercard = em.merge(oldUserIduserOfMovementWisaFastercardListMovementWisaFastercard);
                }
            }
            for (MovementFailpal movementFailpalListMovementFailpal : user.getMovementFailpalList()) {
                User oldUserIduserOfMovementFailpalListMovementFailpal = movementFailpalListMovementFailpal.getUserIduser();
                movementFailpalListMovementFailpal.setUserIduser(user);
                movementFailpalListMovementFailpal = em.merge(movementFailpalListMovementFailpal);
                if (oldUserIduserOfMovementFailpalListMovementFailpal != null) {
                    oldUserIduserOfMovementFailpalListMovementFailpal.getMovementFailpalList().remove(movementFailpalListMovementFailpal);
                    oldUserIduserOfMovementFailpalListMovementFailpal = em.merge(oldUserIduserOfMovementFailpalListMovementFailpal);
                }
            }
            for (Movement movementListMovement : user.getMovementList()) {
                User oldUserIduserOfMovementListMovement = movementListMovement.getUserIduser();
                movementListMovement.setUserIduser(user);
                movementListMovement = em.merge(movementListMovement);
                if (oldUserIduserOfMovementListMovement != null) {
                    oldUserIduserOfMovementListMovement.getMovementList().remove(movementListMovement);
                    oldUserIduserOfMovementListMovement = em.merge(oldUserIduserOfMovementListMovement);
                }
            }
            for (MovementTransfer movementTransferListMovementTransfer : user.getMovementTransferList()) {
                User oldUserIduserOfMovementTransferListMovementTransfer = movementTransferListMovementTransfer.getUserIduser();
                movementTransferListMovementTransfer.setUserIduser(user);
                movementTransferListMovementTransfer = em.merge(movementTransferListMovementTransfer);
                if (oldUserIduserOfMovementTransferListMovementTransfer != null) {
                    oldUserIduserOfMovementTransferListMovementTransfer.getMovementTransferList().remove(movementTransferListMovementTransfer);
                    oldUserIduserOfMovementTransferListMovementTransfer = em.merge(oldUserIduserOfMovementTransferListMovementTransfer);
                }
            }
            utx.commit();
        } catch (Exception ex) {
            try {
                utx.rollback();
            } catch (Exception re) {
                throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(User user) throws NonexistentEntityException, RollbackFailureException, Exception {
        EntityManager em = null;
        try {
            utx.begin();
            em = getEntityManager();
            User persistentUser = em.find(User.class, user.getIduser());
            List<MovementWisaFastercard> movementWisaFastercardListOld = persistentUser.getMovementWisaFastercardList();
            List<MovementWisaFastercard> movementWisaFastercardListNew = user.getMovementWisaFastercardList();
            List<MovementFailpal> movementFailpalListOld = persistentUser.getMovementFailpalList();
            List<MovementFailpal> movementFailpalListNew = user.getMovementFailpalList();
            List<Movement> movementListOld = persistentUser.getMovementList();
            List<Movement> movementListNew = user.getMovementList();
            List<MovementTransfer> movementTransferListOld = persistentUser.getMovementTransferList();
            List<MovementTransfer> movementTransferListNew = user.getMovementTransferList();
            List<MovementWisaFastercard> attachedMovementWisaFastercardListNew = new ArrayList<MovementWisaFastercard>();
            for (MovementWisaFastercard movementWisaFastercardListNewMovementWisaFastercardToAttach : movementWisaFastercardListNew) {
                movementWisaFastercardListNewMovementWisaFastercardToAttach = em.getReference(movementWisaFastercardListNewMovementWisaFastercardToAttach.getClass(), movementWisaFastercardListNewMovementWisaFastercardToAttach.getIdmovementWisaFastercard());
                attachedMovementWisaFastercardListNew.add(movementWisaFastercardListNewMovementWisaFastercardToAttach);
            }
            movementWisaFastercardListNew = attachedMovementWisaFastercardListNew;
            user.setMovementWisaFastercardList(movementWisaFastercardListNew);
            List<MovementFailpal> attachedMovementFailpalListNew = new ArrayList<MovementFailpal>();
            for (MovementFailpal movementFailpalListNewMovementFailpalToAttach : movementFailpalListNew) {
                movementFailpalListNewMovementFailpalToAttach = em.getReference(movementFailpalListNewMovementFailpalToAttach.getClass(), movementFailpalListNewMovementFailpalToAttach.getIdmovementPaypal());
                attachedMovementFailpalListNew.add(movementFailpalListNewMovementFailpalToAttach);
            }
            movementFailpalListNew = attachedMovementFailpalListNew;
            user.setMovementFailpalList(movementFailpalListNew);
            List<Movement> attachedMovementListNew = new ArrayList<Movement>();
            for (Movement movementListNewMovementToAttach : movementListNew) {
                movementListNewMovementToAttach = em.getReference(movementListNewMovementToAttach.getClass(), movementListNewMovementToAttach.getIdmovement());
                attachedMovementListNew.add(movementListNewMovementToAttach);
            }
            movementListNew = attachedMovementListNew;
            user.setMovementList(movementListNew);
            List<MovementTransfer> attachedMovementTransferListNew = new ArrayList<MovementTransfer>();
            for (MovementTransfer movementTransferListNewMovementTransferToAttach : movementTransferListNew) {
                movementTransferListNewMovementTransferToAttach = em.getReference(movementTransferListNewMovementTransferToAttach.getClass(), movementTransferListNewMovementTransferToAttach.getIdmovementTransfer());
                attachedMovementTransferListNew.add(movementTransferListNewMovementTransferToAttach);
            }
            movementTransferListNew = attachedMovementTransferListNew;
            user.setMovementTransferList(movementTransferListNew);
            user = em.merge(user);
            for (MovementWisaFastercard movementWisaFastercardListOldMovementWisaFastercard : movementWisaFastercardListOld) {
                if (!movementWisaFastercardListNew.contains(movementWisaFastercardListOldMovementWisaFastercard)) {
                    movementWisaFastercardListOldMovementWisaFastercard.setUserIduser(null);
                    movementWisaFastercardListOldMovementWisaFastercard = em.merge(movementWisaFastercardListOldMovementWisaFastercard);
                }
            }
            for (MovementWisaFastercard movementWisaFastercardListNewMovementWisaFastercard : movementWisaFastercardListNew) {
                if (!movementWisaFastercardListOld.contains(movementWisaFastercardListNewMovementWisaFastercard)) {
                    User oldUserIduserOfMovementWisaFastercardListNewMovementWisaFastercard = movementWisaFastercardListNewMovementWisaFastercard.getUserIduser();
                    movementWisaFastercardListNewMovementWisaFastercard.setUserIduser(user);
                    movementWisaFastercardListNewMovementWisaFastercard = em.merge(movementWisaFastercardListNewMovementWisaFastercard);
                    if (oldUserIduserOfMovementWisaFastercardListNewMovementWisaFastercard != null && !oldUserIduserOfMovementWisaFastercardListNewMovementWisaFastercard.equals(user)) {
                        oldUserIduserOfMovementWisaFastercardListNewMovementWisaFastercard.getMovementWisaFastercardList().remove(movementWisaFastercardListNewMovementWisaFastercard);
                        oldUserIduserOfMovementWisaFastercardListNewMovementWisaFastercard = em.merge(oldUserIduserOfMovementWisaFastercardListNewMovementWisaFastercard);
                    }
                }
            }
            for (MovementFailpal movementFailpalListOldMovementFailpal : movementFailpalListOld) {
                if (!movementFailpalListNew.contains(movementFailpalListOldMovementFailpal)) {
                    movementFailpalListOldMovementFailpal.setUserIduser(null);
                    movementFailpalListOldMovementFailpal = em.merge(movementFailpalListOldMovementFailpal);
                }
            }
            for (MovementFailpal movementFailpalListNewMovementFailpal : movementFailpalListNew) {
                if (!movementFailpalListOld.contains(movementFailpalListNewMovementFailpal)) {
                    User oldUserIduserOfMovementFailpalListNewMovementFailpal = movementFailpalListNewMovementFailpal.getUserIduser();
                    movementFailpalListNewMovementFailpal.setUserIduser(user);
                    movementFailpalListNewMovementFailpal = em.merge(movementFailpalListNewMovementFailpal);
                    if (oldUserIduserOfMovementFailpalListNewMovementFailpal != null && !oldUserIduserOfMovementFailpalListNewMovementFailpal.equals(user)) {
                        oldUserIduserOfMovementFailpalListNewMovementFailpal.getMovementFailpalList().remove(movementFailpalListNewMovementFailpal);
                        oldUserIduserOfMovementFailpalListNewMovementFailpal = em.merge(oldUserIduserOfMovementFailpalListNewMovementFailpal);
                    }
                }
            }
            for (Movement movementListOldMovement : movementListOld) {
                if (!movementListNew.contains(movementListOldMovement)) {
                    movementListOldMovement.setUserIduser(null);
                    movementListOldMovement = em.merge(movementListOldMovement);
                }
            }
            for (Movement movementListNewMovement : movementListNew) {
                if (!movementListOld.contains(movementListNewMovement)) {
                    User oldUserIduserOfMovementListNewMovement = movementListNewMovement.getUserIduser();
                    movementListNewMovement.setUserIduser(user);
                    movementListNewMovement = em.merge(movementListNewMovement);
                    if (oldUserIduserOfMovementListNewMovement != null && !oldUserIduserOfMovementListNewMovement.equals(user)) {
                        oldUserIduserOfMovementListNewMovement.getMovementList().remove(movementListNewMovement);
                        oldUserIduserOfMovementListNewMovement = em.merge(oldUserIduserOfMovementListNewMovement);
                    }
                }
            }
            for (MovementTransfer movementTransferListOldMovementTransfer : movementTransferListOld) {
                if (!movementTransferListNew.contains(movementTransferListOldMovementTransfer)) {
                    movementTransferListOldMovementTransfer.setUserIduser(null);
                    movementTransferListOldMovementTransfer = em.merge(movementTransferListOldMovementTransfer);
                }
            }
            for (MovementTransfer movementTransferListNewMovementTransfer : movementTransferListNew) {
                if (!movementTransferListOld.contains(movementTransferListNewMovementTransfer)) {
                    User oldUserIduserOfMovementTransferListNewMovementTransfer = movementTransferListNewMovementTransfer.getUserIduser();
                    movementTransferListNewMovementTransfer.setUserIduser(user);
                    movementTransferListNewMovementTransfer = em.merge(movementTransferListNewMovementTransfer);
                    if (oldUserIduserOfMovementTransferListNewMovementTransfer != null && !oldUserIduserOfMovementTransferListNewMovementTransfer.equals(user)) {
                        oldUserIduserOfMovementTransferListNewMovementTransfer.getMovementTransferList().remove(movementTransferListNewMovementTransfer);
                        oldUserIduserOfMovementTransferListNewMovementTransfer = em.merge(oldUserIduserOfMovementTransferListNewMovementTransfer);
                    }
                }
            }
            utx.commit();
        } catch (Exception ex) {
            try {
                utx.rollback();
            } catch (Exception re) {
                throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
            }
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = user.getIduser();
                if (findUser(id) == null) {
                    throw new NonexistentEntityException("The user with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws NonexistentEntityException, RollbackFailureException, Exception {
        EntityManager em = null;
        try {
            utx.begin();
            em = getEntityManager();
            User user;
            try {
                user = em.getReference(User.class, id);
                user.getIduser();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The user with id " + id + " no longer exists.", enfe);
            }
            List<MovementWisaFastercard> movementWisaFastercardList = user.getMovementWisaFastercardList();
            for (MovementWisaFastercard movementWisaFastercardListMovementWisaFastercard : movementWisaFastercardList) {
                movementWisaFastercardListMovementWisaFastercard.setUserIduser(null);
                movementWisaFastercardListMovementWisaFastercard = em.merge(movementWisaFastercardListMovementWisaFastercard);
            }
            List<MovementFailpal> movementFailpalList = user.getMovementFailpalList();
            for (MovementFailpal movementFailpalListMovementFailpal : movementFailpalList) {
                movementFailpalListMovementFailpal.setUserIduser(null);
                movementFailpalListMovementFailpal = em.merge(movementFailpalListMovementFailpal);
            }
            List<Movement> movementList = user.getMovementList();
            for (Movement movementListMovement : movementList) {
                movementListMovement.setUserIduser(null);
                movementListMovement = em.merge(movementListMovement);
            }
            List<MovementTransfer> movementTransferList = user.getMovementTransferList();
            for (MovementTransfer movementTransferListMovementTransfer : movementTransferList) {
                movementTransferListMovementTransfer.setUserIduser(null);
                movementTransferListMovementTransfer = em.merge(movementTransferListMovementTransfer);
            }
            em.remove(user);
            utx.commit();
        } catch (Exception ex) {
            try {
                utx.rollback();
            } catch (Exception re) {
                throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<User> findUserEntities() {
        return findUserEntities(true, -1, -1);
    }

    public List<User> findUserEntities(int maxResults, int firstResult) {
        return findUserEntities(false, maxResults, firstResult);
    }

    private List<User> findUserEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(User.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public User findUser(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(User.class, id);
        } finally {
            em.close();
        }
    }

    public int getUserCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<User> rt = cq.from(User.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
    
}
